package net.quanter.shield.utils.string;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import net.quanter.shield.utils.maths.MathUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符工具类
 *
 * @author 王老实
 * @see org.apache.commons.lang3.StringUtils
 * @since 1.3.12.RELEASE
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

    private final static int DEFAULT_STRING_LENGTH = 6;
    private final static char DEFAULT_STRING_SEPARATOR = ',';
    public final static Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
    public final static Pattern LINE_PATTERN = Pattern.compile("_(\\w)");
    public final static char UNDER_LINE = '_';

    /**
     * 随机生成字符串
     *
     * @param length     6
     * @param complexity StringComplexity.NUMS_AND_ALLCHARS
     * @return aU6z5M
     */
    public static String genString(int length, StringComplexity complexity) {
        length = length <= 0 ? DEFAULT_STRING_LENGTH : length;
        complexity = complexity == null ? StringComplexity.defaultStringComplexity() : complexity;
        StringBuilder stringBuilder = new StringBuilder();
        char[] complexityArrayLength = complexity.getChars();
        for (int i = 0; i < length; i++) {
            int index = MathUtils.getRandom(complexityArrayLength.length);
            stringBuilder.append(complexity.getChars()[index]);
        }
        return stringBuilder.toString();
    }

    /**
     * 拼接字符串
     *
     * @param array     {1,2,3}
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (1_2_3)
     */
    public static String joinString(final int[] array, final char separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 拼接字符串
     *
     * @param array     {1,2,3}
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (1_2_3)
     */
    public static String joinString(final long[] array, final char separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 拼接字符串
     *
     * @param array     {a,b,c}
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (a_b_c)
     */
    public static String joinString(final char[] array, final char separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 拼接字符串
     *
     * @param array     {1.1,2.2,3.3}
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (1.1_2.2_3.3)
     */
    public static String joinString(final double[] array, final char separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 拼接字符串
     *
     * @param array     {aa,bb,cc}
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (aa_bb_cc)
     */
    public static String joinString(final String[] array, final String separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 拼接字符串
     *
     * @param array     list(aa,bb,cc)
     * @param separator _
     * @param prefix    (
     * @param suffix    )
     * @return (aa_bb_cc)
     */
    public static String joinString(Iterable<?> array, final String separator, final String prefix, final String suffix) {
        Preconditions.checkNotNull(array);
        return prefix +
            org.apache.commons.lang3.StringUtils.join(array, separator) +
            suffix;
    }

    /**
     * 字符串转int数字
     *
     * @param str "11,22,33"
     * @return {11,22,33)
     */
    public static int[] stringToIntArray(String str) {
        Preconditions.checkNotNull(str);
        return stringToIntArray(str, DEFAULT_STRING_SEPARATOR);
    }

    /**
     * 字符串转int数组
     *
     * @param str "11,22,33"
     * @param separator ,
     * @return {11,22,33)
     */
    public static int[] stringToIntArray(String str, char separator) {
        return stringToIntArray(str, String.valueOf(separator));
    }

    /**
     * 字符串转int数组
     *
     * @param str       "11,22,33"
     * @param separator ,
     * @return {11,22,33)
     */
    public static int[] stringToIntArray(String str, String separator) {
        List<Integer> list = new ArrayList<>();
        Splitter.on(separator)
            .trimResults()
            .omitEmptyStrings()
            .split(str)
            .forEach(x -> list.add(Integer.parseInt(x)));
        return Ints.toArray(list);
    }

    /**
     * 字符串转long数组
     *
     * @param str "11,22,33"
     * @return {11,22,33)
     */
    public static long[] stringToLongArray(String str) {
        return stringToLongArray(str, DEFAULT_STRING_SEPARATOR);
    }

    /**
     * 字符串转long数组
     *
     * @param str       "11,22,33"
     * @param separator ,
     * @return {11,22,33)
     */
    public static long[] stringToLongArray(String str, char separator) {
        return stringToLongArray(str, String.valueOf(separator));
    }

    /**
     * 字符串转long数组
     *
     * @param str       "11,22,33"
     * @param separator ,
     * @return {11,22,33)
     */
    public static long[] stringToLongArray(String str, String separator) {
        List<Long> list = new ArrayList<>();
        Splitter.on(separator)
            .trimResults()
            .omitEmptyStrings()
            .split(str)
            .forEach(x -> list.add(Long.parseLong(x)));
        return Longs.toArray(list);
    }

    /**
     * 字符串转double数组
     *
     * @param str "11.1,22.2,33.3"
     * @return {11.1,22.2,33.3)
     */
    public static double[] stringToDoubleArray(String str) {
        return stringToDoubleArray(str, DEFAULT_STRING_SEPARATOR);
    }

    /**
     * 字符串转double数组
     *
     * @param str       "11.1,22.2,33.3"
     * @param separator ,
     * @return {11.1,22.2,33.3)
     */
    public static double[] stringToDoubleArray(String str, char separator) {
        return stringToDoubleArray(str, String.valueOf(separator));
    }

    /**
     * 字符串转double数组
     *
     * @param str       "11.1,22.2,33.3"
     * @param separator ,
     * @return {11.1,22.2,33.3)
     */
    public static double[] stringToDoubleArray(String str, String separator) {
        List<Double> list = new ArrayList<>();
        Splitter.on(separator)
            .trimResults()
            .omitEmptyStrings()
            .split(str)
            .forEach(x -> list.add(Double.parseDouble(x)));
        return Doubles.toArray(list);
    }

    /**
     * 将驼峰型字符串转换为带_的
     *
     * @param str aHelloWorld
     * @return a_hello_world
     */
    public static String humpToLine(String str) {
        if (str == null) {
            return null;
        }
        Matcher matcher = HUMP_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, UNDER_LINE + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 将下划线转化为带驼峰的
     *
     * @param str a_b
     * @return aB
     */
    public static String lineToHump(String str) {
        Preconditions.checkNotNull(str);
        Matcher matcher = LINE_PATTERN.matcher(str.toLowerCase());
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 用给定的字符替换字符串中间部分，一般用于安全加密
     *
     * @param str       13800001234
     * @param maxLength 4
     * @param c         *
     * @return 138****1234
     */
    public static String replaceMiddleWith(String str, int maxLength, char c) {
        if (isBlank(str)) {
            return EMPTY;
        }
        if (str.length() < 3) {
            return str;
        }
        int length = maxLength < str.length() - 2 ? maxLength : str.length() - 2;
        int frontLength = (str.length() - length) / 2;
        return str.substring(0, frontLength) + String.valueOf(c).repeat(length) + str.substring(frontLength+length);
        //String phone = "18771632488";
        //System.out.println(str.replaceAll("(\\d{""3""})\\d{4}(\\d{4})","$1****$2"));
        //return null;
    }
}
